 #include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

//需要读取的文件绝对路径
static char *file_path[] = {
    "/sys/bus/iio/devices/iio:device0/in_voltage_scale",
    "/sys/bus/iio/devices/iio:device0/in_voltage1_raw",
};

enum path_index {
    IN_VOLTAGE_SCALE = 0,
    IN_VOLTAGE1_RAW,
};

typedef struct adc_dev_s
{
    int raw; //原始数据，数字值
    float scale;//精度值
    float act;  //实际值
    float conc; //浓度值
}adc_dev_t;

static int file_data_read(char *filename, char *buf, size_t buf_size);

int main(int argc, char *argv[])
{
    char adc_buf[30] = {};
    adc_dev_t mq2;

    memset(&mq2, 0, sizeof(mq2));
    while(1)
    {
        if(file_data_read(file_path[IN_VOLTAGE_SCALE], adc_buf, sizeof(adc_buf)) < 0)
        {
            printf("Error : Read %s failure.\n", file_path[0]);
        }
        mq2.scale = atof(adc_buf);//将字符串转换为浮点类型
        // printf("Read ADC scale = %f\n", mq2.scale);

        if(file_data_read(file_path[IN_VOLTAGE1_RAW], adc_buf, sizeof(adc_buf)) < 0)
        {
            printf("Error : Read %s failure.\n", file_path[1]);
        }
        mq2.raw = atoi(adc_buf);//将字符串转换为整型
        // printf("Read ADC raw = %d\n", mq2.raw);

        mq2.act = (mq2.raw * mq2.scale) / 1000.f;//计算其实际电压值
        mq2.conc = ((float)mq2.raw / 4095.f) * 100.f;//计算其实际浓度值
        printf("MQ-2 实际电压值为 %.3fV , 浓度为%.1f%%\n", mq2.act, mq2.conc);
        sleep(1);
    }
    return 0;
}

//读取文件的字符串
static int file_data_read(char *filename, char *buf, size_t buf_size)
{
    int ret = 0;
    int fd = -1;

    if(!filename || !buf || !buf_size)
    {
        printf("Error filename or str \n");
        return -1;
    }

    fd = open(filename, O_RDONLY);
    if(fd < 0)
    {
        printf("Open file '%s' failure: %s\n", filename, strerror(errno));
        ret = -2;
        goto cleanup;
    }

    memset(buf, 0, buf_size);
    if(read(fd, buf, buf_size) < 0)
    {
        printf("Read data from '%s' failure: %s\n", filename, strerror(errno));
        ret = -3;
        goto cleanup;  
    }

cleanup:
    if(fd >= 0)
        close(fd);   
    
    return ret;
}
